#include "ModuleSTIP.h"

void ModuleSTIP::init(QCVModuleHandlerInterface * parent)
{
	win=new QWidget();
	this->parent=parent;

	stip.init(5,11,11,0.0,1.0,1.0,true,1.0);

	win=new QWidget();
	layout=new QGridLayout(win);

	labelParamK=new QLabel(trUtf8("Paramètre de saillance (k)"),win);
	labelParamSigmaS=new QLabel(tr("Gaussien spatial (SigmaS)"),win);
	labelParamSigmaT=new QLabel(tr("Gaussien temporel (SigmaT)"),win);
	
	labelParamDimX=new QLabel(tr("Dimension X filtre spatial (DimX)"),win);
	labelParamDimY=new QLabel(tr("Dimension Y filtre spatial (DimY)"),win);
	labelParamDimT=new QLabel(tr("Dimension du filtre temporel (DimT)"),win);
	labelParamThreshold=new QLabel(tr("Seuil binaire (S)"),win);
		
	use_mask=new QCheckBox(tr("Utiliser un mask"),win);

	slideParamK=new QSlider(Qt::Horizontal,win);
	slideParamSigmaS=new QSlider(Qt::Horizontal,win);
	slideParamSigmaT=new QSlider(Qt::Horizontal,win);
	slideParamThreshold=new QSlider(Qt::Horizontal,win);
	slideParamK->setRange(0,RESOLUTION);
	slideParamSigmaS->setRange(2,RESOLUTION);
	slideParamSigmaT->setRange(2,RESOLUTION);
	slideParamThreshold->setRange(1,10*RESOLUTION);
	
	spinBoxParamDimX=new QSpinBox();
	
	spinBoxParamDimX->setSingleStep(2.0);
	spinBoxParamDimX->setRange(3,51);
	spinBoxParamDimY=new QSpinBox();
	
	spinBoxParamDimY->setSingleStep(2.0);
	spinBoxParamDimY->setRange(3,51);
	spinBoxParamDimT=new QSpinBox();
	
	spinBoxParamDimT->setSingleStep(2.0);
	spinBoxParamDimT->setRange(3,51);	
	spinBoxParamThreshold=new QDoubleSpinBox();
	

	spinBoxParamK=new QDoubleSpinBox();
	spinBoxParamSigmaS=new QDoubleSpinBox();
	spinBoxParamSigmaT=new QDoubleSpinBox();
	spinBoxParamK->setRange(0,MAXIMUM);
	spinBoxParamSigmaS->setRange(MAXIMUM/RESOLUTION,MAXIMUM);
	spinBoxParamSigmaT->setRange(MAXIMUM/RESOLUTION,MAXIMUM);
	spinBoxParamThreshold->setRange(MAXIMUM/(10*RESOLUTION),MAXIMUM);

	spinBoxParamK->setSingleStep(MAXIMUM/RESOLUTION);
	spinBoxParamSigmaS->setSingleStep(MAXIMUM/RESOLUTION*2);
	spinBoxParamSigmaT->setSingleStep(MAXIMUM/RESOLUTION*2);

	spinBoxParamThreshold->setSingleStep(MAXIMUM/RESOLUTION);
	
	spinBoxParamK->setDecimals(3);
	spinBoxParamSigmaS->setDecimals(3);
	spinBoxParamSigmaT->setDecimals(3);
	spinBoxParamThreshold->setDecimals(5);
	
	select_output=new QComboBox(win);
	select_output->addItem("saillance");
	select_output->addItem("dx2");
	select_output->addItem("dy2");
	select_output->addItem("dt2");
	select_output->addItem("dt");
	select_output->addItem("dxdy_dydx");
	select_output->addItem("dxdt_dtdx");
	select_output->addItem("dydt_dtdy");
	select_output->addItem("keyspoints");

	layout->addWidget(labelParamK,0,0);
	layout->addWidget(labelParamSigmaS,1,0);
	layout->addWidget(labelParamSigmaT,2,0);
	layout->addWidget(labelParamDimX,3,0);
	layout->addWidget(labelParamDimY,4,0);
	layout->addWidget(labelParamDimT,5,0);
	layout->addWidget(labelParamThreshold,6,0);

	layout->addWidget(spinBoxParamK,0,1);
	layout->addWidget(spinBoxParamSigmaS,1,1);
	layout->addWidget(spinBoxParamSigmaT,2,1);
	layout->addWidget(spinBoxParamDimX,3,1);
	layout->addWidget(spinBoxParamDimY,4,1);
	layout->addWidget(spinBoxParamDimT,5,1);
	layout->addWidget(spinBoxParamThreshold,6,1);

	layout->addWidget(slideParamK,0,2);
	layout->addWidget(slideParamSigmaS,1,2);
	layout->addWidget(slideParamSigmaT,2,2);
	layout->addWidget(slideParamThreshold,6,2);
	
	layout->addWidget(select_output,7,0);
	layout->addWidget(use_mask,8,0);

	connect(slideParamK,SIGNAL(valueChanged(int)),this,SLOT(setK(int)));
	connect(slideParamSigmaS,SIGNAL(valueChanged(int)),this,SLOT(setSigmaS(int)));
	connect(slideParamSigmaT,SIGNAL(valueChanged(int)),this,SLOT(setSigmaT(int)));
	connect(slideParamThreshold,SIGNAL(valueChanged(int)),this,SLOT(setThreshold(int)));
	
	connect(spinBoxParamK,SIGNAL(valueChanged(double)),this,SLOT(setK(double)));
	connect(spinBoxParamSigmaS,SIGNAL(valueChanged(double)),this,SLOT(setSigmaS(double)));
	connect(spinBoxParamSigmaT,SIGNAL(valueChanged(double)),this,SLOT(setSigmaT(double)));
	connect(spinBoxParamThreshold,SIGNAL(valueChanged(double)),this,SLOT(setThreshold(double)));
	
	connect(spinBoxParamDimX,SIGNAL(valueChanged(int)),this,SLOT(setDimX(int)));
	connect(spinBoxParamDimY,SIGNAL(valueChanged(int)),this,SLOT(setDimY(int)));
	connect(spinBoxParamDimT,SIGNAL(valueChanged(int)),this,SLOT(setDimT(int)));
	
	connect(select_output,SIGNAL(currentIndexChanged(int)),this,SLOT(setOutput(int)));

	spinBoxParamSigmaS->setValue(stip.getSigmaS());
	spinBoxParamSigmaT->setValue(stip.getSigmaT());
	spinBoxParamDimX->setValue(stip.getDimX());
	spinBoxParamDimY->setValue(stip.getDimY());
	spinBoxParamDimT->setValue(stip.getDimT());
	spinBoxParamThreshold->setValue(stip.getThreshold());
}
////////////////////////////////////////////////////////////////////////////////
void ModuleSTIP::free()
{
	
}
////////////////////////////////////////////////////////////////////////////////
cv::Mat & ModuleSTIP::process()
{	
	return stip.process();
}
////////////////////////////////////////////////////////////////////////////////
void ModuleSTIP::setInput(int n,const cv::Mat & m)
{
	if(n==0)
	{
		stip.push(m);
	}
	if(n==1)
	{
		stip.setMask(m);
	}
}
////////////////////////////////////////////////////////////////////////////////
QWidget* ModuleSTIP::widget()
{
	return win;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleSTIP::getName()
{
	return tr("STIP");
}
////////////////////////////////////////////////////////////////////////////////
int ModuleSTIP::nbInputs()
{
	return 1+use_mask->isChecked();
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleSTIP::getParams()
{
  return QString::number(stip.getK())+tr(";")+
				 QString::number(stip.getSigmaS())+tr(";")+
				 QString::number(stip.getSigmaT())+tr(";")+
				 QString::number(stip.getDimX())+tr(";")+
				 QString::number(stip.getDimY())+tr(";")+
				 QString::number(stip.getDimT())+tr(";")+
				 QString::number(stip.getThreshold())+tr(";")+
				 QString::number(select_output->currentIndex())+tr(";")+
				 QString::number(use_mask->isChecked());
}
////////////////////////////////////////////////////////////////////////////////
bool ModuleSTIP::setParams(QString params)
{
  QStringList list_params=params.split(";");
		
	if(list_params.size()==9)
	{
		stip.setK(list_params[0].toFloat());
		stip.setSigmaS(list_params[1].toFloat());
		stip.setSigmaT(list_params[2].toFloat());
		stip.setDimX(list_params[3].toFloat());
		stip.setDimY(list_params[4].toFloat());
		stip.setDimT(list_params[5].toFloat());
		stip.setThreshold(list_params[6].toFloat(),true);

		spinBoxParamK->setValue(list_params[0].toFloat());
		spinBoxParamSigmaS->setValue(list_params[1].toFloat());
		spinBoxParamSigmaT->setValue(list_params[2].toFloat());
		spinBoxParamDimX->setValue(list_params[3].toFloat());
		spinBoxParamDimY->setValue(list_params[4].toFloat());
		spinBoxParamDimT->setValue(list_params[5].toFloat());
		spinBoxParamThreshold->setValue(list_params[6].toFloat());

		select_output->setCurrentIndex(list_params[7].toInt());
		use_mask->setChecked(list_params[8].toInt());

		return true;
	}
	else
	{
		return false;
	}
}

QCVModuleInterface * ModuleSTIP::clone()
{
	return new ModuleSTIP;
}

////////////////////////////////////////////////////////////////////////////////
QString ModuleSTIP::help(int id)
{	
	if(id==-2)
	{
		return tr("Module d'extraction de coins spatio temporel.");
	}
	else if(id==-1)
	{
		if(select_output->currentIndex()<8)
		{
			return tr("image");
		}
		else
		{
			return tr("keyspoints");
		}
	}
	else if(id==0)
	{	
		return tr("image");
	}
	else if(id==1)
	{
		return tr("image");
	}	
	else
	{
		return tr("erreur");
	}
}
////////////////////////////////////////////////////////////////////////////////
void ModuleSTIP::setDimX(int X){stip.setDimX(X);}
void ModuleSTIP::setDimY(int Y){stip.setDimY(Y);}
void ModuleSTIP::setDimT(int T){stip.setDimT(T);}

void ModuleSTIP::setK(int K)
{
	stip.setK(MAXIMUM*(double)(K)/RESOLUTION);
	spinBoxParamK->setValue(stip.getK());
}
void ModuleSTIP::setSigmaS(int SigmaS)
{
	stip.setSigmaS(MAXIMUM*(double)(SigmaS)/RESOLUTION);
	spinBoxParamSigmaS->setValue(stip.getSigmaS());
}
void ModuleSTIP::setSigmaT(int SigmaT)
{
	stip.setSigmaT(MAXIMUM*(double)(SigmaT)/RESOLUTION);
	spinBoxParamSigmaT->setValue(stip.getSigmaT());
}
void ModuleSTIP::setThreshold(int Threshold)
{
	stip.setThreshold(true,MAXIMUM*(double)(Threshold)/(10*RESOLUTION));
	spinBoxParamThreshold->setValue(stip.getThreshold());
}

void ModuleSTIP::setK(double K)
{
	stip.setK(K);
	slideParamK->setValue(K*RESOLUTION/MAXIMUM);
}
void ModuleSTIP::setSigmaS(double SigmaS)
{
	stip.setSigmaS(SigmaS);
	slideParamSigmaS->setValue(SigmaS*RESOLUTION/MAXIMUM);
}
void ModuleSTIP::setSigmaT(double SigmaT)
{
	stip.setSigmaT(SigmaT);
	slideParamSigmaT->setValue(SigmaT*RESOLUTION/MAXIMUM);
}
void ModuleSTIP::setThreshold(double Threshold)
{
	stip.setThreshold(true,Threshold);
	slideParamThreshold->setValue(Threshold*10*RESOLUTION/MAXIMUM);
}
void ModuleSTIP::setOutput(int id)
{
	stip.setOutput(id);
}
////////////////////////////////////////////////////////////////////////////////
Q_EXPORT_PLUGIN2(ModuleSTIP_plugin,ModuleSTIP);
